/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - core/memory
// Copyright( c) 2013.  All Rights Reserved
//
// File:		AEFreeListAllocator.h
// Author:		Gianluca Belardelli
// Date:		03/10/2013
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AEFREELISTALLOCATOR_H_
#define _AEFREELISTALLOCATOR_H_

class AE_COREDLLIMPEXP AEFreeListAllocator : public AEMemoryAllocator
{
// Members
private:
	struct AEAllocationHeader
	{
		AEUINT32 uiBlockSize:28;
		AEUINT32 uiAdjBytes:4;
	};

	struct AEFreeBlock
    {
		AEUINT32	uiSize;
		AEFreeBlock *lpNextBlock;
	}; 
 
	AEFreeBlock			*m_lpFreeBlocks;
	AEMemoryAllocator	*m_lpParentAllocator;
	AEUINT8				*m_lpBlockStart;

	AEUINT32			m_uiPoolSize;
	AEUINT32			m_uiAllocSize;

protected:
public:

// Methods
private:
	void _expandPoolSize( void );
	void _cleanUp( void );

	AE_DECLARE_NON_COPYABLE( AEFreeListAllocator );
protected:
public:
	AE_DECLARE_PLACEMENT_ALLOCATOR();

	AEFreeListAllocator( void );
	AEFreeListAllocator( AEUINT32 uiSize, AEMemoryAllocator *lpParentAllocator = 0L );

	~AEFreeListAllocator( void ) { _cleanUp(); }

	/// Allocate numBytes.
	/// Allocations of zero bytes may return either the null pointer or
	/// act as if numBytes was nonzero.
	virtual void *BlockAlloc( AEUINT32 uiNumBytes, AEMemoryAlign maAlign = AEMEM_ALIGN16 );

	/// Free numBytes. This method needs to handle p being null, as well
	/// as matching the handling of zero byte allocations as described in blockAlloc.
	virtual void BlockFree( void *lpPtr, AEUINT32 uiNumBytes );

	virtual void GetMemoryStats( AEMemStats &msMemStats );

	virtual AEINT32 GetAllocatedSize( const void *lpObj, AEINT32 nBytes );
};

#endif // _AEFREELISTALLOCATOR_H_
